/**
 * Diplomova prace
 * - GPIO pin 4 nastaven jako vstupni
 * - pridan listener na GPIO port 4
 *      - v pripade zmeny hodnoty tohoto pinu - odeslana SMS o padu (pokud nedojde ke zruseni v ATmega)
 * ----------------------------------------------------------------------------------------------------
 * - pozdeji moznost pridani i vystupniho pinu - zpetna signalizace z modemu do ATmega (nejake zpetne overeni, apod.)
 */
package tcinert;

import com.siemens.icm.io.ATCommand;
import com.siemens.icm.io.ATCommandFailedException;
import com.siemens.icm.io.ATCommandResponseListener;
import com.siemens.icm.io.InPort;
import com.siemens.icm.io.InPortListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Vector;
import javax.microedition.io.CommConnection;
import javax.microedition.io.Connection;
import javax.microedition.io.Connector;
import javax.microedition.io.InputConnection;
import javax.microedition.io.OutputConnection;
import javax.microedition.midlet.MIDlet;


/**
 * @version 0.6
 * @author Tomas Cinert
 */
public class Diplomka06 extends MIDlet {
    ATCommand at;
    ATCommandResponseListener listener;
    InPortListener pinListener;
    String kvalita;
    InputStream input;
    Vector pin;
    InPort pinos;
    int c;
    char temp;
    CommConnection spojeni;
    OutputStream output;
    byte[] a;
    int index = 0;
    
    /**
     * Konstruktor
     * - inicializovan port cislo 4
     * - otevreni serioveho spojeni (pro testovaci ucely)
     *
     **/
    public Diplomka06() {
        try {
            at = new ATCommand(false);
            pin=new Vector(1);        // Vektor o jednom prvku = potrebujeme jenom jeden pin
            pin.addElement("GPIO4");      // Pin cislo 4
            //values=new Vector(1);           Ukazka jak pracovat s vystupnim pinem
            //values.addElement(Integer.valueOf("0"));        Nastaven na 0
        } catch (ATCommandFailedException ex) {
            ex.printStackTrace();
        } catch (IllegalStateException ex) {
            ex.printStackTrace();
        }
        listener = new ATCommandResponseListener()         // Listener na odezvu na ATprikazy
        {
            public void ATResponse(String Response) {
                // zapisCOM(Response);
                if (Response.startsWith("+CSQ", 2)) {
                    kvalita = Response;
                }
                
                if (Response.startsWith("ERROR", 2)) {
                    
                    destroyApp(true);
                    notifyDestroyed();
                }
                
                else if (Response.startsWith("+CREG:", 2)) {
                    if (!Response.startsWith("+CREG: 0,1", 2)) {
                        poslaniSMS("Konfigurace selhala");
                        destroyApp(true);
                        notifyDestroyed();
                    }
                }
            }
        };
        
        try { // Vytvoreni spojeni na portu COM0 s rychlosti 115200 pro Cteni/Zapis s povolenym timeoutem - pokud dojde k preteceni je generovana vyjimka
            spojeni = ((CommConnection)Connector.open("comm:COM0;baudrate=115200", 3, true));
            input = spojeni.openInputStream();
            output = spojeni.openOutputStream();
            String zprava = "Spojeni otevreno";
            zapisCOM(zprava);
        } catch (IOException ex) {
            destroyApp(true);
            notifyDestroyed();
        }
        try {
            pinos=new InPort(pin);      // Otevreni vstupniho pinu
        } catch (IOException ex) {
            zapisCOM(ex.toString());    // Pokud uz je otevreni         
        }
        pinos.addListener(pinListener=new InPortListener(){           // Pridani listeneru 
            public void portValueChanged( int value )  {        // metoda na zachyceni zmeny hodnoty
                zapisCOM("PAdnul jsem");        // Testovaci vypis
                poslaniSMS("Zdary. Padnul jsem. Port c.4 je"+value);    // Odeslani SMS s textem plus hodnotou pinu
            }
        });
             
        
    }
    /**
     * Metoda na poslani AT prikazu
     * - po odeslani je vlakno uspano na 1 sekundu z duvodu cekani na vykonani prikazu,
     *  jelikoz je pouzita neblokujici varianta metody send
     */
    
    public void poslaniSMS(String text) {
        ATsend("AT+CMGS=\"+420604450956\"\r");   // Cislo na ktere bude poslana SMS
        ATsend(text+ '\032');  // TExt SMS zpravy
    }
    public void ATsend(String ATprikaz) {
        try {
            at.send(ATprikaz, listener);
            Thread.sleep(1000L);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (ATCommandFailedException ex) {
            ex.printStackTrace();
        } catch (IllegalStateException ex) {
            ex.printStackTrace();
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
    }
    /**
     * Metoda na zapis dat na seriovy port
     *@param zprava
     */
    public void zapisCOM(String zprava) {
        try {
            output.write(zprava.getBytes());
        } catch (IOException e) {
        }
    }
    
    /**
     * Spousteci metoda MIDletu
     * - je volana po spusteni MIDletu
     * - vypsana hodnota pinu po startu
     * - yapis hodnotz portu po stisku tlacitka - pouzito na zkouseni, aby se furt nemusela posilat SMS
     **/
    public void startApp() {
        ATsend("AT+CMGF=1\r");
        try {
            zapisCOM(Integer.toString(pinos.getValue()));
        } catch (IOException ex) {
            ex.printStackTrace();
        }   
        
        while (temp != '\r') {
            try {
                
                c = input.read();
                zapisCOM(Integer.toString(pinos.getValue()));
               
                
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            temp = (char)c;
            
            zapisCOM(String.valueOf(temp));
            
        }
        
  
        
        destroyApp(true);
        notifyDestroyed();
    }
    
    public void pauseApp() {
    }
    /**
     * Metoda na zavreni databaze a serioveho spojeni
     */
    public void uzavreniSpojeni() {
        try {
            
            pinos.release();    // Zavreni pinu
           
            input.close();
            output.close();
            spojeni.close();
            
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    public void destroyApp(boolean unconditional) {
        zapisCOM("Koncime");        // Testovaci vypis
        uzavreniSpojeni();
    }
}